package generadorDescriptores;

import generadorDescriptores.database.ConnectionManager;
import generadorDescriptores.dom.JoinsDom;
import generadorDescriptores.dom.XmlDocument;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.w3c.dom.Document;

import com.project.frba.bi.BiUtil;
import com.project.frba.bi.descriptor.DatabaseDescriptor;
import com.project.frba.bi.descriptor.Dimension;
import com.project.frba.bi.descriptor.Join;
import com.project.frba.bi.descriptor.JoinCondition;
import com.project.frba.bi.descriptor.Property;

public class FileInCreation {
	String name; 
	String database; 
	DatabaseDescriptor descriptor; 
	XmlDocument xmlDocument;
	ConnectionManager connectionManager; 
	
	
	public FileInCreation(){
		xmlDocument = new XmlDocument();
		descriptor = new DatabaseDescriptor(xmlDocument.getDocument());
	}
	
	public void setConnectionManager(ConnectionManager conManager){
		this.connectionManager = conManager;
	}
	
	public ConnectionManager getConnectionManager(){
		return this.connectionManager;
	}
	
	
	public void setDatabase(String database){
		this.database = database;
	}
	
	public void setBiName(String biName){
		this.name = biName;
		this.descriptor.setDescriptorName(biName);
	}
	
	public void setBiLabel(String biLabel){
		this.descriptor.setLabel(biLabel);
	}
	
	public void setPrivilege(String privilege){
		this.descriptor.setPrivilege(privilege);
	}
	
	public String getDatabase(){
		return this.database;
	}
	
	public void setFacttable(String facttable){
		this.descriptor.setFacttable(facttable);
	}
	
	public void setMetric(String metric){
		this.descriptor.setMetric(metric);
	}
	
	public void setMetricType(String type){
		this.descriptor.setMetricType(BiUtil.getMetricType(type));
	}
	
	public String getFacttable(){
		return this.descriptor.getFacttable();
	}
	
	public Collection<Dimension> getDimensions(){
		return descriptor.getDimensions();
	}
	
	public void removeDimension(String dimensionName){
		this.descriptor.removeDimension(dimensionName);
	}
	
	public DatabaseDescriptor getDescriptor(){
		return this.descriptor;
	}
	
	public void addDimension(Dimension dimension){
		descriptor.addDimension(dimension);
	}
	
	public void addJoin(Join join){
		descriptor.addJoin(join);
	}
	
	public void addPropertyToDimension(String dimensionName, Property property){
		for (Iterator iterator = getDimensions().iterator(); iterator.hasNext();) {
			Dimension dimension = (Dimension) iterator.next();
			if(dimension.getName().equals(dimensionName)){
				dimension.addProperty(property);
			}
		}
	}
	
	public void removePropertyFromDimension(String dimensionName, String propertyName){
		Collection<Dimension> dimensions = descriptor.getDimensions();
		for (Iterator iterator = dimensions.iterator(); iterator.hasNext();) {
			Dimension dim = (Dimension) iterator.next();
			if(dim.getName().equals(dimensionName)){
				dim.removeProperty(propertyName);
			}
		}
	}
	
	public Dimension getDimensionByName(String dimensionName){
		Collection<Dimension> dimensions = this.getDimensions(); 
		for (Iterator iterator = dimensions.iterator(); iterator.hasNext();) {
			Dimension dim = (Dimension) iterator.next();
			if(dim.getName().equals(dimensionName)){
				return dim;
			}
		}
		return null;
	}
	
	public Property getPropertyByName(String dimensionName, String propertyName){
		Collection<Dimension> dimensions = this.getDimensions();
		for (Iterator iterator = dimensions.iterator(); iterator.hasNext();) {
			Dimension dim = (Dimension) iterator.next();
			if(dim.getName().equals(dimensionName)){
				return dim.getProperty(propertyName);
			}
		}
		return null;
	}
	
	public Collection<Join> getJoins(){
		return descriptor.getJoins();
	}
	
	public void removeConditionFromJoin(String joinName, String conditionName){
		Collection<Join> joins = getDescriptor().getJoins();
		for (Iterator iterator = joins.iterator(); iterator.hasNext();) {
			Join join = (Join) iterator.next();
			if(join.getName().equals(joinName)){
				ArrayList<JoinCondition> conditions = join.getJoinConditions(); 
				for (int i = 0; i < conditions.size(); i++) {
					if(conditionName.contains(conditions.get(i).toString())){
						join.removeJoinCondition(conditions.get(i));
					}
				}
			}
		}
	}
	
	public void addConditionToJoin(String joinName, JoinCondition joinCondition){
		Collection<Join> joins = descriptor.getJoins();
		for (Iterator iterator = joins.iterator(); iterator.hasNext();) {
			Join join = (Join) iterator.next();
			if(join.getName().equals(joinName)){
				join.addJoinCondition(joinCondition);
			}
		}
	}
	
	public Document convertToDocument(){
		XmlDocument xml = new XmlDocument();
		AttributesData data = new AttributesData();
		data.setBiName(descriptor.getDescriptorName().toLowerCase());
		data.setBiLabel(descriptor.getLabel());
		data.setBiPrivilege(descriptor.getPrivilege());
		data.setFacttableTable(descriptor.getFacttable());
		data.setMetric(descriptor.getMetric().toLowerCase());
		data.setFormatter(descriptor.getFormatterClassName());
		if(descriptor.getCurrencyType()!=null){
			data.setCurrencyType(descriptor.getCurrencyType().toString());
		}			
		Class metricType = descriptor.getMetricType();
		String typeAsString = BiUtil.typeClassToString(metricType);
		data.setFacttableType(typeAsString.toLowerCase());
		xml.buildDescriptorAndFacttable(data);
		
		xml.addTagJoins();
		Collection<Join> joins = descriptor.getJoins();
		for (Iterator iterator = joins.iterator(); iterator.hasNext();) {
			Join join = (Join) iterator.next();
			//AttributesData data2 = new AttributesData();
			data.setJoinName(join.getName().toLowerCase());
			data.setJoinTable(join.getTable());
			ArrayList<JoinCondition>conditions = join.getJoinConditions();
			for (int i = 0; i < conditions.size(); i++) {
				data.setConditionJoinColumn(conditions.get(i).getColumn());
				data.setConditionJoinFactColumn(conditions.get(i).getFactColumn());
				xml.addConditionToJoin(join.getName().toLowerCase(), data);
			}			
		}
		
		xml.addTagDimensions();
		Collection<Dimension>dimensions = descriptor.getDimensions();
		for (Iterator iterator = dimensions.iterator(); iterator.hasNext();) {
			Dimension dim = (Dimension) iterator.next();
			data.setDimensionName(dim.getName().toLowerCase());
			Collection<Property> props = dim.getProperties();
			for (Iterator iterator2 = props.iterator(); iterator2.hasNext();) {
				Property prop = (Property) iterator2.next();
				data.setPropName(prop.getName().toLowerCase());
				data.setPropLabel(prop.getLabel());
				data.setPropColumn(prop.getColumn());
				data.setPropTable(prop.getTable());
				data.setPropDefault(prop.getDefaultValue());
				data.setPropFunction(prop.getFunction().toLowerCase());
				data.setPropType(BiUtil.typeClassToString(prop.getType()));
				xml.addPropertyToDimension(data, dim.getName().toLowerCase());
			}
		}
		return xml.getDocument();
	}
	
	public void setFormatter(String formatter){
		descriptor.setFormatterClassName(formatter);
	}
	
	public String getFormatter(){
		return descriptor.getFormatterClassName();
	}
	
	public void setCurrencyType(int type){
		descriptor.setCurrencyType(type);
	}
	
	public int getCurrencyType(){
		return descriptor.getCurrencyType();
	}
	
	public Join getJoinByName(String joinName){
		Collection<Join> joins = this.descriptor.getJoins();
		for (Iterator iterator = joins.iterator(); iterator.hasNext();) {
			Join join = (Join) iterator.next();
			if(join.getName().equals(joinName)){
				return join;
			}
		}
		return null;
	}
	
	
}
